package calao.contact.client;

import java.util.HashMap;
import java.util.Iterator;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.ImageBundle;

import calao.client.Desktop;
import calao.client.DesktopFeature;
import calao.client.ServiceCallback;
import calao.client.util.IntMap;

/** Calao contact management client module.
 */
public class ContactMod 
extends DesktopFeature 
{
	
	static ContactMod instance;
	
	public interface Images extends ImageBundle 
	{
		AbstractImagePrototype contactCard();
	}
	
	public final Text text = (Text)GWT.create(Text.class);
	public final Images images = (Images)GWT.create(Images.class);
	final ContactShortcuts shortcuts = new ContactShortcuts(this);
	
	ContactServiceAsync service;
	private IntMap contactMap;
	private IntMap groupMap;
	private long refreshTime = 0;
	boolean refreshPending = false;
	
	public ContactMod()
	{
		instance = this;
	}
	
	public void activate()
	{
		getDesktop().register(shortcuts);
		getDesktop().register(ContactService.MODIFY_CONTACTS, text.manageContacts(), this);
		refreshContacts();
	}

	public String getDescription() 
	{
		return text.contactModDesc();
	}

	public String getTitle() 
	{
		return text.contactMod();
	}

	public String getApplicationName() 
	{
		return "calao.contact";
	}
		
	private void setInfo(Contact[] info)
	{
		IntMap map = new IntMap();
		for (int i=0; i<info.length; i++) {
			map.put(info[i].id, info[i]);
		}
		contactMap = map;
		shortcuts.contactList.refreshWith(info);
	}
		
	private void setInfo(Group[] info)
	{
		IntMap map = new IntMap();
		for (int i=0; i<info.length; i++) {
			map.put(info[i].id, info[i]);
		}
		groupMap = map;
	}

	public boolean ready()
	{
		return contactMap!=null;
	}
	
	public Iterator listContacts()
	{
		HashMap map = contactMap;
		if (map==null) map = new HashMap();
		return map.values().iterator();
	}
	
	public Iterator listGroups()
	{
		HashMap map = groupMap;
		if (map==null) map = new HashMap();
		return map.values().iterator();		
	}
	
	public Contact getContact(int id)
	{
		return contactMap!=null? (Contact)contactMap.get(id) : null;
	}
	
	public String getContactName(int id)
	{
		Contact info = getContact(id);
		return info!=null? info.getLabel() : text.contactX(id);
	}
	
	public String getGroupName(int groupId)
	{
		Group group = (Group)groupMap.get(groupId);
		return group!=null? group.name : "("+group.id+")";
	}

	public void refreshContacts()
	{
		if ((System.currentTimeMillis()-refreshTime)<2000) return;
		if (!refreshPending) {
			refreshPending = true;
			log("Fetching contact list");
			getService().listContacts(-1, -1, 1, new ServiceCallback() {
				public void onReturn(Object result) {
					setInfo((Contact[])result);
				}
			});
			refreshGroups();
			ServiceCallback.defer(new Command() {
				public void execute() {
					refreshPending = false;
					refreshTime = System.currentTimeMillis();
				}
			});
		}
	}
	
	void refreshGroups()
	{
		getService().listGroups(new ServiceCallback() {
			public void onReturn(Object result) {
				setInfo((Group[])result);
			}
		});		
	}
	
	public static ContactMod getMod()
	{
		return instance;
	}
	
	ContactServiceAsync getService()
	{
		if (service==null) {
			service = (ContactServiceAsync)getDesktop().bindService(
					GWT.create(ContactService.class), "calao.contact.client.ContactService");		
		}
		return service;
	}
	
	static boolean canModify()
	{
		return Desktop.getDesktop().has(ContactService.MODIFY_CONTACTS);
	}
	
}
